package com.mondo.financialwallet.presentation.ui.activity;

import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.common.ui.BaseActivity;
import com.example.common.zxing.ui.CaptureActivity;
import com.mondo.financialwallet.R;
import com.mondo.financialwallet.data.DataRepository;
import com.mondo.financialwallet.presentation.model.Token;
import com.mondo.financialwallet.data.params.TokenTransferParams;
import com.mondo.financialwallet.presentation.event.RequestWalletAssetEvent;
import com.mondo.financialwallet.presentation.ui.dialog.PayDetailsBottomDialog;
import com.mondo.financialwallet.presentation.ui.dialog.TipsDialog;
import com.mondo.financialwallet.presentation.ui.dialog.VerificationPasswordDialog;
import com.mondo.financialwallet.presentation.utils.ActivityTitleBarHelper;
import com.mondo.financialwallet.presentation.utils.AndroidUtils;
import com.mondo.financialwallet.presentation.utils.LocalConfigStorage;
import com.mondo.financialwallet.presentation.utils.Toasts;

import org.greenrobot.eventbus.EventBus;

import java.text.DecimalFormat;
import java.util.List;
import java.util.Objects;

import butterknife.Bind;
import pub.devrel.easypermissions.AppSettingsDialog;
import pub.devrel.easypermissions.EasyPermissions;

import static com.example.common.zxing.ui.CaptureActivity.INTENT_EXTRA_KEY_QR_SCAN;

/**
 * 转账
 */
public class TokenTransferActivity extends BaseActivity implements EasyPermissions.PermissionCallbacks {

    private static final String EXTRA_TOKEN = "TOKEN", EXTRA_ADDRESS = "ADDRESS";
    private static final int REQ_CODE = 2;

    public static void launch(Context context, Token token) {
        context.startActivity(
                new Intent(context, TokenTransferActivity.class)
                        .putExtra(EXTRA_TOKEN, token)
        );
    }

    public static void launch(Context context, Token token, String address) {
        context.startActivity(
                new Intent(context, TokenTransferActivity.class)
                        .putExtra(EXTRA_TOKEN, token)
                        .putExtra(EXTRA_ADDRESS, address)
        );
    }

    @Bind(R.id.action_image) ImageView mActionImageView;
    @Bind(R.id.gas_text_view) TextView mGasTextView;
    @Bind(R.id.transfer_amount_edit) EditText mTransferAmountEdit;
    @Bind(R.id.all_transfer_view) TextView mAllTransferView;
    @Bind(R.id.address_text_view) EditText mAddressEditText;
    @Bind(R.id.remark_text_view) EditText mRemarkTextView;
    @Bind(R.id.setting_gas_layout) View mSettingGasLayout;
    @Bind(R.id.select_token_layout) View mSelectTokenLayout;
    @Bind(R.id.confirm_transfer_view) View mConfirmTransferView;
    @Bind(R.id.token_logo_image) ImageView mTokenLogoImage;
    @Bind(R.id.token_name_text_view) TextView mTokenNameTextView;
    @Bind(R.id.token_amount_text_view) TextView mTokenAmountTextView;

    private Token mToken;

    @Override
    protected int getLayoutID() {
        return R.layout.activity_transfer;
    }

    @Override
    protected void initActions() {
        mToken = (Token) getIntent().getSerializableExtra(EXTRA_TOKEN);
        String address = getIntent().getStringExtra(EXTRA_ADDRESS);

        // 标题
        ActivityTitleBarHelper.init(this, R.string.title_transfer);
        mActionImageView.setImageResource(R.drawable.ic_scan_rq);
        mActionImageView.setOnClickListener(v -> openRqCodeActivity());

        // 货币信息
        displayTokenInfoInView();

        // 选择其他token
        mSelectTokenLayout.setOnClickListener(v ->
                TokenSelectActivity.launch(this, REQ_CODE));

        // 所以金额
        mAllTransferView.setOnClickListener(v -> transferAllAmount());

        // 转入地址
        if (!TextUtils.isEmpty(address)) {
            mAddressEditText.setText(address);
        }

        // 转账
        mConfirmTransferView.setOnClickListener(v -> {
            if (TextUtils.isEmpty(mTransferAmountEdit.getText())) {
                Toasts.warning(R.string.message_please_enter_transfer_amount);
                return;
            }

            startTransfer(new TokenTransferParams(
                    mToken.getId(),
                    mAddressEditText.getText().toString(),
                    mToken.getAddress(),
                    String.valueOf(mToken.getGas()),
                    mRemarkTextView.getText().toString(),
                    Double.parseDouble(mTransferAmountEdit.getText().toString())
            ));
        });
    }

    private void displayTokenInfoInView() {
        Glide.with(this).load(mToken.getCover()).into(mTokenLogoImage);
        mTokenNameTextView.setText(mToken.getName());
        mTokenAmountTextView.setText(String.format(getString(R.string.text_balance_placeholder),
                mToken.getCny()));
        mGasTextView.setText(String.valueOf(mToken.getGas()));
    }

    private void transferAllAmount() {
        // 余额小于手续费
        if (Double.parseDouble(mToken.getCny()) < mToken.getGas()) {
            mTransferAmountEdit.setText("0");
        } else {
            mTransferAmountEdit.setText(new DecimalFormat("########.########")
                    .format(Double.parseDouble(mToken.getCny()) - mToken.getGas()));
        }

        AndroidUtils.setTextAndSelectionEnd(mTransferAmountEdit);
    }

    private void startTransfer(TokenTransferParams params) {
        // 判断余额是否可以转账
        if (Double.parseDouble(mToken.getCny()) < mToken.getGas()
                || Double.parseDouble(mToken.getCny()) - mToken.getGas()
                < Double.parseDouble(mTransferAmountEdit.getText().toString())) {
            TipsDialog.failure(this)
                    .build(R.string.message_transfer_failed, R.string.message_unable_transfer)
                    .show();
            return;
        }

        if (params.getAmount() <= 0) {
            Toasts.warning(R.string.message_please_enter_transfer_amount);
            return;
        }

        if (TextUtils.isEmpty(params.getToAddress())) {
            Toasts.warning(R.string.message_please_select_address);
            return;
        }

        // 密码验证
        new PayDetailsBottomDialog(this).show(params, v ->
                VerificationPasswordDialog
                        .login()
                        .setPositive(dialog -> {
                            String password = dialog.getText();
                            if (!LocalConfigStorage.get().getPassword().equals(password)) {
                                dialog.setErrorMessage(getString(R.string.message_password_error));
                            } else {
                                transfer(params, dialog);
                            }
                        })
                        .build(this)
                        .show()
        );
    }

    private void transfer(TokenTransferParams params, VerificationPasswordDialog dialog) {
        DataRepository.get().transfer(params, result -> {

            if (result.isSuccess()) {
                dialog.dismiss();
                Toasts.success(R.string.message_transfer_success);
                EventBus.getDefault().post(new RequestWalletAssetEvent());
                finish();
            } else {
                dialog.setErrorMessage(result.getMsg());
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_OK && requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
            CaptureActivity.launch(this);
        } else if (resultCode == 0xA1 && data != null) {
            Bundle bundle = data.getExtras();
            String scanResult = Objects.requireNonNull(bundle).getString(INTENT_EXTRA_KEY_QR_SCAN);
            mAddressEditText.setText(scanResult);
        } else if (requestCode == REQ_CODE && data != null) {
            mToken = (Token) data.getSerializableExtra("TOKEN");
            displayTokenInfoInView();
            mTransferAmountEdit.setText(null);
        }
    }

    private void openRqCodeActivity() {
        String[] permissions = new String[]{Manifest.permission.CAMERA};
        if (!EasyPermissions.hasPermissions(this, permissions)) {
            String rationale = getString(R.string.please_approve_camera_permissions);
            EasyPermissions.requestPermissions(this, rationale, 0, permissions);
        } else {
            CaptureActivity.launch(this);
        }
    }

    @Override
    public void onRequestPermissionsResult(
            int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        CaptureActivity.launch(this);
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            new AppSettingsDialog.Builder(this).setTitle(R.string.auto_authorization_failure)
                    .setRationale(R.string.please_manually_select_approve_camera_permissions).build().show();
        } else {
            Toasts.failure(R.string.authorization_failure);
        }
    }

}
